
#ifndef __DATA_CENTER_CLIENT__
#define __DATA_CENTER_CLIENT__

#include <atomic>
#include <unordered_map>
#include <vector>
#include <tuple>
#include "IClient.h"
#include "IThreadPoolManager.h"
#include "ISysResources.h"


typedef struct
{
	string strReqBuf;
    long long llLastReqTime;
}ST_MONITOR_LBM;

class CCheckDataCentre : public virtual IWork
{
INIT_CLASS_PRODUCT(CCheckDataCentre);
public:
	const bool Init(const void * pvdPara, char * pszMsgTxt, int iMsgTxtSize);
	void * Work();

private:
	shared_ptr<IClient> m_ptrClient;

};

class CDataCenterClient: public virtual IClient
{
INIT_CLASS_SINGLETON(CDataCenterClient)
public:
	const bool AfterInit();
	const bool InitClient(const PST_StartServerSidePara ptrStartServerSidePara);
	const bool DataConnectEd();
	const bool CreateDataConnect(PST_StartServerSidePara ptrStartServerSidePara);
    const bool DisableDataConnect();
    const void SendHeartbeat();
    const bool InitKcbpConnectInfo(PST_KCBP_CONNECT_INFO ptrKcbpConnectInfo);
    const bool SendASynReqTask(const char * pszConnectId, IData * ptrTask);
    const bool SendASynReqTask(const char * pszConnectId, const char * pszTask);
    const bool SendSyncReqTask(const char * pszConnectId, IData * ptrTask, IData ** ptrRetVal, int iTimeOut);
    const bool SendSyncReqTask(const char * pszConnectId, const char * pszTask, char ** pszRetVal, int & iLen, int iTimeOut);
	const bool KcbpRunAsynTask(const char * pszTask, const char * pszIpAdd = nullptr);
	const bool KcbpRunAsynTask(IPacket * ptrTask, const char * pszIpAdd = nullptr);
	const bool KcbpRunSyncTask(const char * pszTask, char ** pszRetVal, int & refiSize, int iTimeOut, const char * pszIpAdd);
	const bool KcbpRunSyncTask(IPacket * ptrTask, IPacket ** ptrRetVal, int iTimeOut, const char * pszIpAdd);
	const bool MaRunAsynTask(const char * pszTask, const char * pszIpAdd);
	const bool MaRunAsynTask(IPacket * ptrTask, const char * pszIpAdd);
	const bool MaRunSyncTask(const char * pszTask, char ** pszRetVal, unsigned long & refiSize, int iTimeOut, const char * pszIpAdd);
	const bool MaRunSyncTask(IPacket * ptrTask, IPacket ** ptrRetVal, int iTimeOut, const char * pszIpAdd);
	const bool MaRunSubTask(const char * pszTask, char ** pszRetVal, unsigned long & refiSize, int iTimeOut, const char * pszIpAdd);
	const bool MaRunSubTask(IPacket * ptrTask, IPacket ** ptrRetVal, int iTimeOut, const char * pszIpAdd);
	const bool MaRunUnSubTask(const char * pszTask, char ** pszRetVal, unsigned long & refiSize, int iTimeOut);
	const bool MaRunUnSubTask(IPacket * ptrTask, IPacket ** ptrRetVal, int iTimeOut);

	const unsigned long long GetLastRunTime();
	const void SetLastRunTime(unsigned long long ullValue);
	const int DsOutTime();
	const char * MntLbmNo();
	void SetDsOutTime(const int iDsOutTime);
	void SetMntLbmNo(const char * pszMntLbmNo);
	void DeleteMntLbm(const long long llSeqNo);
	const bool CheckDataCentre();

private:
	::DWORD m_dwDsProcessId;
	ST_StartServerSidePara m_clStartServerSidePara;
	string m_strDataCenterFileName, m_strHeartbeat;
	shared_ptr<ILock> m_ptrLockSyncReq, m_ptrDcLock;
	atomic<bool> m_bDataConnectEd; 
	string m_strUserCode, m_strSession, m_strRunTime, m_strOpUser;
	volatile long long m_ullLastRunTime, m_ullCount;
	//atomic< volatile unsigned long long> m_ullLastRunTime;
	int m_iDsOutTime;
	string m_strMntLbmNo;
	unordered_map<long long, shared_ptr<ST_MONITOR_LBM>> m_mpMntLbm;
	vector<string> m_vtSubList;
	atomic<bool> m_bFlg;
	unordered_map<string, unordered_map<string, tuple<int, string>>> m_mpDataConnectId;

private:
	void AppendMntLbm(const long long llSeqNo, const char * pszReqBuf);	
	void CheckMntLbm();
	const unsigned long GetDCProcessId();
	void SetDCProcessId(const unsigned long ulProcessId);
	const char * GetDataConnectId(const char * pszConnectId);
	tuple<int, string> * GetConnectInfo(const char * pszConnectId);

};




#endif//__DATA_CENTER_CLIENT__